package com.qk.config;

import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.qk.enums.DateTimeEnum;
import com.qk.exception.CommonException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.context.annotation.Bean;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

/**
 * @Author: zhangchuang
 * @Date: 2025/09/29 10:04
 * @Description: 全局时间格式化类
 */
@JsonComponent
@Slf4j
@SuppressWarnings("all")
public class DateFormatConfig {

    @Value("${spring.jackson.date-format}")
    private String DATE_TIME_PATTERN;
    private final static String DATE_Z = "Z";
    private final static String DATE_T = "T";

    /**
     * LocalDateTime 序列化器
     */
    @Bean
    public LocalDateTimeSerializer localDateTimeSerializer() {
        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN));
    }

    // 自定义反序列化器处理带Z的字符串
    @Bean
    public JsonDeserializer<LocalDateTime> localDateTimeDeserializer() {
        return new JsonDeserializer<>() {
            @Override
            public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt)
                    throws IOException {
                String dateString = p.getText();
                try {
                    // 处理带Z的UTC时间字符串
                    if (StrUtil.endWith(dateString, DATE_Z)) {
                        return LocalDateTime.parse(
                                StrUtil.sub(dateString, 0, dateString.length() - 1),
                                DateTimeFormatter.ISO_LOCAL_DATE_TIME
                        );
                    } else if (StrUtil.contains(dateString, DATE_T)) {
                        return LocalDateTime.parse(dateString, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
                    }
                    // 处理普通格式
                    return LocalDateTime.parse(dateString, DateTimeFormatter.ofPattern(DATE_TIME_PATTERN));
                } catch (DateTimeParseException e) {
                    log.error("Failed to parse date: " + dateString);
                    CommonException.throwException(DateTimeEnum.DATE_PARSE_ERROR);
                }
                return null;
            }
        };
    }

    /**
     * 注册自定义序列化器
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer(
            LocalDateTimeSerializer localDateTimeSerializer,
            JsonDeserializer<LocalDateTime> localDateTimeDeserializer) {
        return builder -> builder
                .serializerByType(LocalDateTime.class, localDateTimeSerializer)
                .deserializerByType(LocalDateTime.class, localDateTimeDeserializer);
    }
}
